using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Reflection;

namespace FROG
{
    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            _fontNormal = Control.DefaultFont;
            _fontBold = new Font(_fontNormal, FontStyle.Bold);

            App.OpenConnections.ItemAdded += new ListChangedEventHandler<OpenConnection>(OpenConnections_ItemAdded);
            App.OpenConnections.ItemRemoved += new ListChangedEventHandler<OpenConnection>(OpenConnections_ItemRemoved);
            App.WorkSheets.ItemAdded += new ListChangedEventHandler<WorkSheet>(WorkSheets_ItemAdded);
            App.WorkSheets.ItemRemoved += new ListChangedEventHandler<WorkSheet>(WorkSheets_ItemRemoved);
        }

        private Dictionary<OpenConnection, ToolStripDropDownButton> _connectionDropDowns = new Dictionary<OpenConnection, ToolStripDropDownButton>();
        private Dictionary<WorkSheet, ToolStripMenuItem> _workSheetMenuItems = new Dictionary<WorkSheet, ToolStripMenuItem>();

        private void mnuNewConnection_Click(object sender, EventArgs e)
        {
            NewConnection();
        }

        private void NewConnection()
        {
            ConnectionDialog dlg = new ConnectionDialog();
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                OpenConnection cnx = dlg.SelectedDatabase.CreateConnection();
                try
                {
                    cnx.Open();
                    NewWorkSheet(cnx);
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error:\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private WorkSheet CreateWorkSheet(OpenConnection cnx)
        {
            WorkSheet ws = CreateWorkSheet();
            ws.Connection = cnx;
            return ws;
        }

        private WorkSheet CreateWorkSheet()
        {
            WorkSheet ws = new WorkSheet();
            ws.Name = "Worksheet" + App.NextWorksheetNumber();
            ws.Text = ws.Name;
            ws.Dock = DockStyle.Fill;
            ws.MdiParent = this;
            ws.ModifiedChanged += new EventHandler(WorkSheet_ModifiedChanged);
            ws.FilenameChanged += new EventHandler(WorkSheet_FilenameChanged);
            ws.DisplayNameChanged += new EventHandler(WorkSheet_DisplayNameChanged);
            ws.ConnectionChanged += new EventHandler(WorkSheet_ConnectionChanged);
            return ws;
        }

        void WorkSheet_ConnectionChanged(object sender, EventArgs e)
        {
            RemoveDropDownItem(sender as WorkSheet);
            CreateDropDownItem(sender as WorkSheet);
            SelectActiveConnection();
        }

        void WorkSheet_DisplayNameChanged(object sender, EventArgs e)
        {
            WorkSheet ws = sender as WorkSheet;
            if (ws != null && _workSheetMenuItems.ContainsKey(ws))
            {
                ToolStripMenuItem mnu = _workSheetMenuItems[sender as WorkSheet];
                mnu.Text = ws.DisplayName;
            }

        }

        void WorkSheet_FilenameChanged(object sender, EventArgs e)
        {
            if (sender == dockPanel.ActiveDocument)
                SetTitle();
        }

        void WorkSheet_ModifiedChanged(object sender, EventArgs e)
        {
            if (sender == dockPanel.ActiveDocument)
                SetTitle();
        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        void WorkSheets_ItemRemoved(object sender, ListChangedEventArgs<WorkSheet> e)
        {
            RemoveDropDownItem(e.Item);
        }

        private void RemoveDropDownItem(WorkSheet ws)
        {
            if (_workSheetMenuItems.ContainsKey(ws))
            {
                ToolStripMenuItem mnu = _workSheetMenuItems[ws];
                ToolStripDropDown parent = mnu.Owner as ToolStripDropDown;
                if (parent != null)
                    parent.Items.Remove(mnu);
                _workSheetMenuItems.Remove(ws);
            }
        }

        void WorkSheets_ItemAdded(object sender, ListChangedEventArgs<WorkSheet> e)
        {
            CreateDropDownItem(e.Item);
        }

        private void CreateDropDownItem(WorkSheet ws)
        {
            if (_workSheetMenuItems.ContainsKey(ws))
                return;
            if (ws.Connection != null && _connectionDropDowns.ContainsKey(ws.Connection))
            {
                ToolStripDropDownButton ddb = _connectionDropDowns[ws.Connection];
                ToolStripMenuItem mnu = new ToolStripMenuItem(ws.DisplayName);
                mnu.Image = Properties.Resources.file;
                mnu.Tag = ws;
                mnu.Font = Control.DefaultFont;
                ddb.DropDownItems.Add(mnu);
                _workSheetMenuItems.Add(ws, mnu);
            }
        }

        void OpenConnections_ItemRemoved(object sender, ListChangedEventArgs<OpenConnection> e)
        {
            RemoveDropDownButton(e.Item);
        }

        private void RemoveDropDownButton(OpenConnection cnx)
        {
            if (_connectionDropDowns.ContainsKey(cnx))
            {
                ToolStripDropDownButton ddb = _connectionDropDowns[cnx];
                tbConnections.Items.Remove(ddb);
                _connectionDropDowns.Remove(cnx);
            }
        }

        void OpenConnections_ItemAdded(object sender, ListChangedEventArgs<OpenConnection> e)
        {
            CreateDropDownButton(e.Item);
        }

        private void CreateDropDownButton(OpenConnection cnx)
        {
            if (_connectionDropDowns.ContainsKey(cnx))
                return;

            ToolStripDropDownButton ddb = new ToolStripDropDownButton(cnx.Database.Name);
            ddb.Image = Properties.Resources.database;
            ddb.DropDownItemClicked += new ToolStripItemClickedEventHandler(ddb_DropDownItemClicked);
            ddb.Tag = cnx;

            ToolStripMenuItem mnu = new ToolStripMenuItem("New worksheet");
            mnu.Image = Properties.Resources.file_add;
            mnu.Tag = cnx;
            mnu.Font = Control.DefaultFont;
            mnu.Click += new EventHandler(tsMnuNewWorkSheet_Click);
            ddb.DropDownItems.Add(mnu);

            mnu = new ToolStripMenuItem("Close connection");
            mnu.Tag = cnx;
            mnu.Font = Control.DefaultFont;
            mnu.Image = Properties.Resources.database_close;
            mnu.Click += new EventHandler(mnuCloseConnection_Click);
            ddb.DropDownItems.Add(mnu);

            ddb.DropDownItems.Add(new ToolStripSeparator());
            tbConnections.Items.Add(ddb);
            _connectionDropDowns.Add(cnx, ddb);
        }

        void ddb_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripMenuItem mnu = e.ClickedItem as ToolStripMenuItem;
            if (mnu != null && mnu.Tag is WorkSheet)
            {
                WorkSheet ws = mnu.Tag as WorkSheet;
                ws.Activate();
            }
        }

        void tsMnuNewWorkSheet_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem mnu = sender as ToolStripMenuItem;
            OpenConnection cnx = mnu.Tag as OpenConnection;
            NewWorkSheet(cnx);
        }

        void mnuCloseConnection_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem mnu = sender as ToolStripMenuItem;
            OpenConnection cnx = mnu.Tag as OpenConnection;
            cnx.Dispose();
        }

        private void SetTitle()
        {
            WorkSheet ws = this.ActiveMdiChild as WorkSheet;
            if (ws != null)
            {
                this.Text = Application.ProductName + " - " + ws.Text;
            }
            else
            {
                this.Text = Application.ProductName;
            }
        }


        private ToolStripDropDownButton _activeDropDown = null;
        private Font _fontNormal;
        private Font _fontBold;

        private void SelectActiveConnection()
        {
            if (_activeDropDown != null)
                _activeDropDown.Font = _fontNormal;
            _activeDropDown = null;
            WorkSheet ws = this.ActiveMdiChild as WorkSheet;
            if (ws != null)
            {
                if (ws.Connection != null && _connectionDropDowns.ContainsKey(ws.Connection))
                {
                    ToolStripDropDownButton ddb = _connectionDropDowns[ws.Connection] as ToolStripDropDownButton;
                    if (ddb != null)
                    {
                        ddb.Font = _fontBold;
                        _activeDropDown = ddb;
                    }

                }
            }
        }

        private void btnNewConnection_Click(object sender, EventArgs e)
        {
            NewConnection();
        }

        private void mnuNewWorkSheet_Click(object sender, EventArgs e)
        {
            NewWorkSheet();
        }

        private void NewWorkSheet()
        {
            WorkSheet ws = CreateWorkSheet();
            ws.Show(dockPanel);
        }

        private void NewWorkSheet(OpenConnection cnx)
        {
            WorkSheet ws = CreateWorkSheet(cnx);
            ws.Show(dockPanel);
        }

        private void MainForm_MdiChildActivate(object sender, EventArgs e)
        {
            SelectActiveConnection();
            SelectActiveWorkSheet();
            SetTitle();
        }

        private void SelectActiveWorkSheet()
        {
            WorkSheet ws = this.ActiveMdiChild as WorkSheet;
            foreach (KeyValuePair<WorkSheet, ToolStripMenuItem> kvp in _workSheetMenuItems)
            {
                kvp.Value.Checked = (kvp.Key == ws);
            }
        }

        private void mnuAbout_Click(object sender, EventArgs e)
        {
            AboutDialog about = new AboutDialog();
            about.ShowDialog();
        }

        private void dockPanel_ActivePaneChanged(object sender, EventArgs e)
        {
            if (dockPanel.ActiveDocumentPane != null && dockPanel.ActiveDocumentPane.ActiveContent != null)
            {
                WorkSheet ws = dockPanel.ActiveDocumentPane.ActiveContent as WorkSheet;
                if (ws != null)
                {
                    this.ActivateMdiChild(ws);
                    this.ActiveControl = ws;
                }
            }
        }
    }
}